#pragma once
#include "stdafx.h"
#include <gdiplus.h>
using namespace Gdiplus;
#include "atlwin.h"
#include "Layered.h"
#include "atlmisc.h"
#include <process.h>
#include <fstream>
#include <string>

using namespace std;



class CCapturePane :
	public CDialogImpl<CCapturePane>, CLayered<CCapturePane>
{
	POINT m_startPt, m_endPt;
	RECT m_rcTrack;
	SIZE m_sizeAll;
	bool m_bTracking;
public:
	CCapturePane(){};
	~CCapturePane(){};

	enum { IDD = IDD_CAPTUREPANE };

	BEGIN_MSG_MAP(CAboutDlg)
		MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_MOUSEMOVE, OnLButtonMove)		
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		ModifyStyle(WS_CAPTION, NULL);

		//::SetWindowLong(m_hWnd, GWL_STYLE, GetStyle() & ~WS_CAPTION);

		RECT rc;
		::GetWindowRect(::GetDesktopWindow(), &rc);

		SetWindowPos(NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW );
		CenterWindow(GetParent());
		SetLayered();
		MakeTransparent(80);
		m_bTracking = false;
		return TRUE;
	}

	LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_bTracking = false;
		::ReleaseCapture();

		ShowWindow(SW_HIDE);

		CRect rScreenshot(m_rcTrack);
		rScreenshot.NormalizeRect();

		// Force repaint of screenshot area
		HWND hDesktop = ::GetDesktopWindow();
		if((hDesktop) && (::IsWindow(hDesktop)))
		{
			::InvalidateRect(hDesktop, NULL, TRUE);
			::UpdateWindow(hDesktop);
			::RedrawWindow(hDesktop, NULL, NULL, RDW_FRAME|
				RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN);
		}

		// Grab screenshot 
		HBITMAP hScreenshotBmp = GetScreenshot(::GetDesktopWindow(), &rScreenshot);
		Bitmap bmp(hScreenshotBmp, NULL);
		CLSID bmpClsid;
		GetEncoderClsid(L"image/bmp", &bmpClsid);
		bmp.Save(L"c:\\screen.bmp", &bmpClsid);


		system( "tesseract.exe c:\\screen.bmp c:\\outputbase -l eng" );

		Sleep(1000);
		wifstream fstrm("c:\\outputbase.txt");
		if( fstrm )
		{
			wstring line, output;

			while(  !fstrm.eof())
			{
				getline( fstrm, line );
				if( line.size() < 1 ) continue;
				if( line[line.size() - 1 ] == '-' ) 
				{
					line.erase(line.size() - 1);
				}
				else
				{
					line += wstring(L" ");
				}
				output += line;
			}

			fstrm.close();

			wofstream ofile("c:\\good.txt");
			ofile<<output;
			ofile.flush();
			ofile.close();

			SetClipboardText(output.c_str());

		}
		EndDialog(IDD_CAPTUREPANE);
		return TRUE;
	}

	LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		m_bTracking = true;

		RECT rc;
		GetWindowRect(&rc);
		m_sizeAll.cx = rc.right - rc.left;
		m_sizeAll.cy = rc.bottom - rc.top;

		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		if(PtInDevRect(pt))
		{
			SetCapture();
			m_bTracking = true;
			::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y);
		}	
		return TRUE;
	}

	LRESULT OnLButtonMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{	
		if(m_bTracking)
		{
			POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
			if(this->PtInDevRect(pt))
			{
				this->DrawTrackRect();
				m_rcTrack.right = pt.x;
				m_rcTrack.bottom = pt.y;
				this->DrawTrackRect();
			}
		}
		return TRUE;
	}	

	// helper

	void DrawTrackRect()
	{
		const SIZE sizeLines = { 2, 2 };
		RECT rc = m_rcTrack;
		if(!::IsRectEmpty(&rc))
		{
			::MapWindowPoints(this->m_hWnd, NULL, (LPPOINT)&rc, 2);
			CWindowDC dc(NULL);
			dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines);
		}
	}

	BOOL PtInDevRect(POINT pt)
	{
		RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy };
		return ::PtInRect(&rc, pt);
	}

	HBITMAP GetScreenshot(HWND hWnd, CRect* pRect/*=NULL*/)
	{
		// Get DC
		HDC hDC = ::GetWindowDC(hWnd);
		HDC hCaptureDC = ::CreateCompatibleDC(hDC);
		int nBPP = ::GetDeviceCaps(hDC, BITSPIXEL);

		// If no rect was supplied grab entire window
		CRect rCapture;
		if(pRect)
			rCapture.CopyRect(pRect);
		else
			::GetWindowRect(hWnd, rCapture);

		// Create device independent bitmap
		BITMAPINFO bmiCapture = {
			sizeof(BITMAPINFOHEADER), 
			rCapture.Width(), -rCapture.Height(), 
			1, nBPP, BI_RGB, 0, 0, 0, 0, 0,
		};
		LPBYTE lpCapture;
		HBITMAP hbmCapture = CreateDIBSection(hDC, &bmiCapture,
			DIB_PAL_COLORS, (LPVOID*)&lpCapture, NULL, 0);
		if(!hbmCapture)
		{
			::DeleteDC(hCaptureDC);
			::DeleteDC(hDC);
			return NULL;
		}

		// Grab the image
		int nCapture = ::SaveDC(hCaptureDC);
		::SelectObject(hCaptureDC, hbmCapture);
		if(pRect)
			::BitBlt(hCaptureDC, 0, 0, rCapture.Width(), rCapture.Height(), hDC, rCapture.left, rCapture.top, SRCCOPY);
		else
			::BitBlt(hCaptureDC, 0, 0, rCapture.Width(), rCapture.Height(), hDC, 0, 0, SRCCOPY);
		::RestoreDC(hCaptureDC, nCapture);
		::DeleteDC(hCaptureDC);
		::DeleteDC(hDC);

		// Return the bitmap handle
		return hbmCapture;
	}

	int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
	{
		UINT  num = 0;          // number of image encoders
		UINT  size = 0;         // size of the image encoder array in bytes

		ImageCodecInfo* pImageCodecInfo = NULL;

		GetImageEncodersSize(&num, &size);
		if(size == 0)
			return -1;  // Failure

		pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
		if(pImageCodecInfo == NULL)
			return -1;  // Failure

		GetImageEncoders(num, size, pImageCodecInfo);

		for(UINT j = 0; j < num; ++j)
		{
			if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
			{
				*pClsid = pImageCodecInfo[j].Clsid;
				free(pImageCodecInfo);
				return j;  // Success
			}    
		}

		free(pImageCodecInfo);
		return -1;  // Failure
	}


	BOOL SetClipboardText(LPCWSTR pszText)
	{
		BOOL ok = FALSE;
		int i = wcslen(pszText);
		if(OpenClipboard()) {
			// the text should be placed in "global" memory
			HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 
				(wcslen(pszText)+1)*sizeof(pszText[0]) );
			LPWSTR ptxt = (LPWSTR)GlobalLock(hMem);      
			memcpy((void*)ptxt, &pszText[0], 
				(wcslen (pszText))*sizeof(pszText[0])); 
			ptxt[wcslen(pszText)] =(TCHAR) 0;
			GlobalUnlock(hMem);
			// set data in clipboard; we are no longer responsible for hMem
			ok = (BOOL)SetClipboardData(CF_UNICODETEXT, hMem);

			CloseClipboard(); // relinquish it for other windows
		}
		return ok;
	}

};

